use aes_gcm::{
    Aes256Gcm, Key, KeyInit, Nonce,
    aead::{Aead, OsRng,rand_core::RngCore},
};
use md5::{Md5, Digest};
use base64::{engine::general_purpose, Engine as _};
use tracing::{error};
use anyhow::Result;

const AES_KEY: &[u8] = b"f82aa0f0b06a47e082d2490298d1f758";
pub fn md5(data: &str) -> String {
    let mut hasher = Md5::new();
    hasher.update(data.as_bytes());
    let hash = hasher.finalize();
    format!("{:x}", hash)
}

/**
 * AES 加密
 */
pub fn aes_encrypt(data: &str) -> Result<String,Box<dyn std::error::Error>> {
    let key = Key::<Aes256Gcm>::from_slice(AES_KEY);
    let cipher = Aes256Gcm::new(&key);
    //生成12为随机 nonce
    let mut nonce_bytes = [0u8; 12];
    OsRng.fill_bytes(&mut nonce_bytes);
    let noce = Nonce::from_slice(&nonce_bytes);

    //加密
    let ciphertext = match cipher.encrypt(&noce, data.as_ref()) {
        Ok(ciphertext) => ciphertext,
        Err(e)=>{
            error!("AES 加密失败:{}",e);
            return Err("AES 加密失败".into())
        }
    };

    //拼接 返回
    let mut buf = Vec::with_capacity(nonce_bytes.len() + ciphertext.len());
    buf.extend_from_slice(&nonce_bytes);
    buf.extend_from_slice(&ciphertext);
    Ok(general_purpose::STANDARD.encode(buf))
}

pub fn aes_decrypt(encrypted_b64:&str)->Result<String,Box<dyn std::error::Error>> {
    let key = Key::<Aes256Gcm>::from_slice(AES_KEY);
    let cipher = Aes256Gcm::new(&key);

    //解码
    let buf = general_purpose::STANDARD.decode(encrypted_b64)
    .map_err(|e| format!("base64解码失败:{}",e))?;
    if buf.len() < 12 {
        error!("密文长度不足12字节");
        return Err("密文长度不足12字节".into());
    }
    let (nonce_bytes,ciphertext) = buf.split_at(12);
    let nonce = Nonce::from_slice(nonce_bytes);
    // 解密
    let plaintext = match cipher.decrypt(&nonce, ciphertext) {
        Ok(plaintext) => plaintext,
        Err(e) => {
            error!("AES 解密失败:{}",e);
            return Err("AES 解密失败".into());
        }
    };
    Ok(String::from_utf8(plaintext).unwrap())
}
